package com.swing.sky.web.generator.util;

import com.google.common.base.CaseFormat;
import com.swing.sky.web.generator.domain.Column;
import com.swing.sky.web.generator.domain.Module;
import com.swing.sky.web.generator.domain.GenColumn;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 数据库与代码之间的映射
 *
 * @author swing
 */
public class MapUtils {
    public static final String BIGINT = "bigint";
    public static final String JDBC_BIGINT = "BIGINT";
    public static final String VARCHAR = "varchar";
    public static final String JDBC_VARCHAR = "VARCHAR";
    public static final String INT = "int";
    public static final String JDBC_INT = "INTEGER";
    public static final String CHAR = "char";
    public static final String JDBC_CHAR = "CHAR";
    public static final String TINYINT = "tinyint";
    public static final String JDBC_TINYINT = "BOOLEAN";
    public static final String DATETIME = "datetime";
    public static final String JDBC_DATETIME = "TIMESTAMP";
    public static final String BOOLEAN_PREFIX = "is_";
    public static final String UNDER_SCORE = "_";


    /**
     * 过滤DO的公共字段
     */
    public static List<GenColumn> filterBasicColumns(List<GenColumn> genColumns) {
        String basicColumns = PropertyUtils.readSky("basicColumns");
        String[] split = basicColumns.split(",");
        List<String> strings = Arrays.asList(split);
        return genColumns.stream().filter(a -> !strings.contains(a.getPropertyName())).collect(Collectors.toList());
    }

    /**
     * 将Column转化为GenColumn
     */
    public static List<GenColumn> getGenColumnsByColumns(List<Column> columns) {
        List<GenColumn> genColumns = new ArrayList<>();
        for (Column column : columns) {
            GenColumn genColumn = new GenColumn(column);
            genColumn.setPropertyName(getPropertyByColumnName(column.getColumnName()));
            genColumn.setGetSetName(toUpperCaseName(genColumn.getPropertyName()));
            genColumn.setPropertyType(getJavaTypeByDataType(column.getDataType()));
            genColumn.setJdbcType(getJdbcTypeByDataType(column.getDataType()));
            genColumns.add(genColumn);
        }
        return genColumns;
    }

    /**
     * 根据表名完善module中的fileName属性
     */
    public static void setFileNameByTableName(String tableName, List<Module> modules) {
        //将下划线转化为开头大写的驼峰命名
        String s = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName);
        for (Module module : modules) {
            String defaultFileName = PropertyUtils.readGen(module.getModuleName() + "." + "defaultFileName");
            if (defaultFileName != null) {
                module.setFileName(defaultFileName);
            } else {
                module.setFileName(s + module.getSuffix());
            }
        }
    }

    /**
     * 示例将字段user_id转化为属性userId
     */
    public static String getPropertyByColumnName(String columnName) {
        if (columnName.startsWith(BOOLEAN_PREFIX)) {
            //依据阿里巴巴规范，是否逻辑使用在数据库中使用tinyint(1)使用is_开头，将其映射为java属性时去掉is_
            String substring = columnName.substring(3);
            return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, substring);
        }
        if (!columnName.contains(UNDER_SCORE)) {
            return columnName;
        }
        return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, columnName);
    }

    /**
     * 使字符串首字母大写
     */
    public static String toUpperCaseName(String name) {
        name = name.substring(0, 1).toUpperCase() + name.substring(1);
        return name;
    }

    /**
     * 使字符串首字母大写
     */
    public static String toLowerCaseName(String name) {
        name = name.substring(0, 1).toLowerCase() + name.substring(1);
        return name;
    }


    /**
     * 解析数据库数据类型
     */
    public static String getJavaTypeByDataType(String dataType) {
        if (BIGINT.equalsIgnoreCase(dataType)) {
            return "Long";
        }
        if (VARCHAR.equalsIgnoreCase(dataType)) {
            return "String";
        }
        if (INT.equalsIgnoreCase(dataType)) {
            return "Integer";
        }
        if (CHAR.equalsIgnoreCase(dataType)) {
            return "String";
        }
        if (TINYINT.equalsIgnoreCase(dataType)) {
            return "Boolean";
        }
        if (DATETIME.equalsIgnoreCase(dataType)) {
            return "Date";
        }
        return "String";
    }

    /**
     * 将数据库类型转化为jdbcType(mapper.xml中使用）
     */
    public static String getJdbcTypeByDataType(String dataType) {
        if (BIGINT.equalsIgnoreCase(dataType)) {
            return JDBC_BIGINT;
        }
        if (VARCHAR.equalsIgnoreCase(dataType)) {
            return JDBC_VARCHAR;
        }
        if (INT.equalsIgnoreCase(dataType)) {
            return JDBC_INT;
        }
        if (CHAR.equalsIgnoreCase(dataType)) {
            return JDBC_CHAR;
        }
        if (TINYINT.equalsIgnoreCase(dataType)) {
            return JDBC_TINYINT;
        }
        if (DATETIME.equalsIgnoreCase(dataType)) {
            return JDBC_DATETIME;
        }
        return JDBC_VARCHAR;
    }

}
